"use strict";
const { exec } = require("child_process");
const util = require("util");
const path = require("path");
const { app } = require("electron"); // 引入Electron app
const { logger } = require("ee-core/log");
const DesCrypto = require("../utils/DesCrypto.js");

/**
 * 协议注册服务
 * @class
 */
class ProtocolService {
  constructor() {
    this.mainWindow = null;
    this.pendingProtocolCall = null; // 缓存协议参数
  }

  setMainWindow(win) {
    this.mainWindow = win;

    // 监听页面加载完成事件
    win.webContents.on("did-finish-load", () => {
      this.onMainWindowReady();
    });
  }
  // 显示主窗口并聚焦
  showMainWindow() {
    if (this.mainWindow && !this.mainWindow.isDestroyed()) {
      if (this.mainWindow.isMinimized()) {
        this.mainWindow.restore(); // 恢复窗口
      }
      this.mainWindow.focus(); // 聚焦窗口
    }
  }
  async registerProtocolWithWindows() {
    const exePath = process.execPath;
    // 标准化路径，处理特殊字符
    const normalizedExePath = path.resolve(exePath);
    const baseKey = "HKCR\\fdeap";

    // 注册表命令数组 - 优化了引号处理和转义
    const registryCommands = [
      `REG ADD "${baseKey}" /ve /d "URL:fdeap Protocol" /f`,
      `REG ADD "${baseKey}" /v "URL Protocol" /t REG_SZ /d "" /f`,
      `REG ADD "${baseKey}" /v "Version" /t REG_SZ /d "1.0" /f`,
      // 处理路径中的空格和特殊字符，正确转义引号
      `REG ADD "${baseKey}\\DefaultIcon" /ve /d "\\"${normalizedExePath}\\"" /f`,
      `REG ADD "${baseKey}\\Shell" /ve /f`,
      `REG ADD "${baseKey}\\Shell\\Open" /ve /f`,
      // 正确转义命令参数中的引号
      `REG ADD "${baseKey}\\Shell\\Open\\Command" /ve /d "\\"${normalizedExePath}\\" \\"%1\\"" /f`,
    ];

    // 将 exec 包装成 Promise 版本
    const execAsync = util.promisify(exec);

    logger.info("开始注册 fdeap 协议...");
    logger.info(`应用程序路径: ${normalizedExePath}`);

    try {
      // 逐个执行命令，确保顺序执行
      for (let i = 0; i < registryCommands.length; i++) {
        const command = registryCommands[i];
        logger.info(
          `执行命令 [${i + 1}/${registryCommands.length}]: ${command}`
        );

        // 增加超时设置，防止命令挂起
        const { stdout } = await execAsync(command, { timeout: 5000 });

        if (stdout) {
          logger.debug(`命令输出: ${stdout.trim()}`);
        }
        logger.info(`命令 [${i + 1}] 执行成功`);
      }

      logger.info("fdeap 协议注册完成");
    } catch (error) {
      // 详细的错误信息
      const errorDetails = {
        command: error.cmd,
        code: error.code,
        signal: error.signal,
        stderr: error.stderr ? error.stderr.trim() : "无错误输出",
      };

      logger.error(`协议注册失败: ${error.message}`, errorDetails);
      throw new Error(
        `注册命令执行失败: ${errorDetails.command}\n错误信息: ${errorDetails.stderr}`
      );
    }
  }

  // 添加协议处理逻辑
  initProtocolHandlers() {
    // 确保单实例运行
    const gotTheLock = app.requestSingleInstanceLock();
    if (!gotTheLock) {
      app.quit();
      return;
    }
    const protocolRegex = /^fdeap:{1,2}\/\//i;
    // 监听协议调用事件
    app.on("second-instance", (event, commandLine) => {
      const protocolUrl = commandLine.find((arg) => protocolRegex.test(arg));
      if (protocolUrl) this.handleProtocolUrl(protocolUrl);
    });

    // 处理首次启动的协议调用
    const protocolUrl = process.argv.find((arg) => protocolRegex.test(arg));
    if (protocolUrl) this.handleProtocolUrl(protocolUrl);
  }

  // 协议URL处理
  handleProtocolUrl(url) {
    logger.info("接收到协议调用:", url);
    this.showMainWindow();

    try {
      url = url.replace(/^fdeap::\/\//i, "fdeap://");
      const urlObj = new URL(url);
      const protocol = urlObj.hostname; // 获取动作类型
      const params = Object.fromEntries(new URLSearchParams(urlObj.search)); // 解析查询参数

      logger.info("解析结果:", { protocol, params });

      // 如果是login协议且存在password参数，则对password进行解密
      if (protocol === "login" && params.password) {
        let key = "15FF3426-3ACD-4E00-7BA7-ABB6573F1F62";
        try {
          params.password = DesCrypto.decrypt(params.password, key);
        } catch (error) {
          logger.error("解密失败:", error);
        }
      }
      // 如果页面已加载完成，直接发送事件
      if (
        this.mainWindow &&
        this.mainWindow.webContents &&
        !this.mainWindow.webContents.isLoading()
      ) {
        this.mainWindow.webContents.send("protocol-call", { protocol, params });
      } else {
        // 否则缓存参数，等待页面加载完成
        this.pendingProtocolCall = { protocol, params };
      }
    } catch (error) {
      console.error("URL 解析失败:", error);
    }
  }

  webLoginSuccess(result) {
    if (this.mainWindow && this.mainWindow.webContents) {
      this.mainWindow.webContents.send("web-login-success", result);
    }
  }

  webLogoutSuccess(result) {
    if (this.mainWindow && this.mainWindow.webContents) {
      this.mainWindow.webContents.send("web-logout-success", result);
    }
  }

  // 页面加载完成后发送缓存的协议参数
  onMainWindowReady() {
    if (
      this.pendingProtocolCall &&
      this.mainWindow &&
      this.mainWindow.webContents
    ) {
      this.mainWindow.webContents.send(
        "protocol-call",
        this.pendingProtocolCall
      );
      this.pendingProtocolCall = null; // 清空缓存
    }
  }
}

module.exports = {
  ProtocolService,
  protocolService: new ProtocolService(),
};